﻿//===============================================================================
// Apolineo Patterns & Practices LeanEngine Framework
//===============================================================================
// Copyright © Apolineo Desenvolvimento de Sistemas Ltda.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================

using System;
using System.Linq;
using System.Text;
using System.Data.Linq.Mapping;

using LeanEngine.Entity;
using LeanEngine.Validation;
using LeanEngine.SalesConcept.Business;

namespace LeanEngine.SalesConcept.Entity
{
    //O atributo Table do namespace System.Data.Linq.Mapping é responsável
    //por informar ao lob que a classe se refere a tabela
    //'SaleDetail' no banco de dados

    //Herdamos da interface IDataTransferObject para o ambiente do lob
    //funcione de acordo, porém, não queremos que gerencie as mudanças
    //nos valores das propriedades, faça atualizações pessimistas e envie
    //no comando update somente os dados alterados, além do, versionamento
    //do dado automaticamente
    [Table(Name = "SaleDetail")]
    public class SaleDetail : PlainEntity
    {
        #region SaleDetail Members

        //Aqui mapeamos a coluna ProductId (seu valor será obtido através da propriedade
        //da classe Product que possui o atributo Column como PK) e adicionamos um validador
        //padrão para assegurar que a propriedade tenha uma instancia válida e sua propriedade
        //pk preenchida, e em caso de erro, lança uma exceção de negócio com a mensagem de erro
        //obtida através do resource 'ErrorMessages', chave 'SelectProductRequired'
        [IsNotNullAndHasPrimaryKeysFilled(typeof(ErrorMessages), "SelectProductRequired"),
        Column(Name = "ProductId")]
        public Product Product
        {
            get;
            set;
        }

        //Aqui mapeamos a coluna 'Quantity' e adicionamos uma validação padrão
        //para assegurar que a quantidade seja maior que 0, e em
        //caso de erro, lança uma exceção de negócio com a mensagem de erro
        //obtida através do resource 'ErrorMessages', chave 'SaleDetailQuantityInvalid'
        [IsGreaterThan(0, typeof(ErrorMessages), "SaleDetailQuantityInvalid"),
        Column(Name = "Quantity")]
        public int Quantity
        {
            get;
            set;
        }

        //Aqui mapeamos a coluna 'Price' e adicionamos uma validação padrão
        //para assegurar que o preço seja maior que 0, e em
        //caso de erro, lança uma exceção de negócio com a mensagem de erro
        //obtida através do resource 'ErrorMessages', chave 'SaleDetailPriceInvalid'
        [IsGreaterThan(0, typeof(ErrorMessages), "SaleDetailPriceInvalid"),
        Column(Name = "Price")]
        public decimal Price
        {
            get;
            set;
        }

        //Aqui mapeamos a coluna 'Price' e adicionamos uma validação padrão
        //para assegurar que o desconto seja maior ou igual a 0, e em
        //caso de erro, lança uma exceção de negócio com a mensagem de erro
        //obtida através do resource 'ErrorMessages', chave 'SaleDetailDiscountInvalid'
        [IsGreaterThanEqual(0, typeof(ErrorMessages), "SaleDetailDiscountInvalid"),
        Column(Name = "Discount")]
        public decimal Discount
        {
            get;
            set;
        }

        //Aqui mapeamos a coluna SaleId (seu valor será obtido através da propriedade
        //da classe Sale que possui o atributo Column como PK) e adicionamos um validador
        //padrão para assegurar que a propriedade tenha uma instancia válida,
        //e em caso de erro, lança uma exceção de negócio com a mensagem de erro
        //obtida através do resource 'ErrorMessages', chave 'SelectProductRequired'

        //Aqui não colocamos o validador IsNotNullAndHasPrimaryKeysFilled porque
        //o valor dessa propriedade só será preenchido após inserção da venda
        [IsNotNull(typeof(ErrorMessages), "SelectSaleRequired"),
        Column(Name = "SaleId")]
        public Sale Sale
        {
            get;
            set;
        }

        //Aqui mapeamos a coluna PK da tabela SaleDetail e informamos ao lob
        //que o valor dela é gerado pelo banco de dados
        [Column(Name = "SaleDetailId", IsDbGenerated = true, IsPrimaryKey = true)]
        public long Id
        {
            get;
            set;
        }

        #endregion
    }
}
